package com.soft.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;

/**
 * 泛型HIBERNATE DAO實現类
 * 
 */
public interface IGenericDao<T extends Serializable> {

	/**
	 * 获得该DAO对应的POJO类型
	 */
	public Class<T> getPojoClass();

	/**
	 * 获得该DAO对应的POJO类型名
	 */
	public String getPojoClassName();

	/**
	 * 加载所有的对象
	 */
	public List<T> loadAll();

	/**
	 * 根据HQL查询數據
	 * 
	 * @param hql
	 *            HQL語句
	 * @param values
	 *            可變參數
	 * @return
	 */
	public List find(String hql, Object... values);

	/**
	 * 根据条件加载对象
	 * 
	 * @param criteria
	 *            Criteria实例
	 */

	public List<T> findByCriteria(final Criteria criteria);

	/**
	 * 根据条件加载对象
	 * 
	 * @param detachedCriteria
	 *            DetachedCriteria实例
	 */
	public List<T> findByCriteria(final DetachedCriteria detachedCriteria);

	/**
	 * 根据给定的实例查找对象
	 * 
	 * @param instance
	 *            實例類
	 * @return
	 */
	public List<T> findByExample(T instance);

	/**
	 * 根据ID查找对象
	 * 
	 * @param id
	 *            主鍵ID
	 * @return
	 */
	public T findById(Serializable id);

	/**
	 * 根据某个具体属性进行查找
	 * 
	 * @param propertyName
	 *            屬性字段名
	 * @param value
	 *            屬性值
	 * @return
	 */
	public List<T> findByProperty(String propertyName, Object value);
	
	public T get(Serializable id);

	/**
	 * 保存对象
	 * 
	 * @param entity
	 *            实体对象
	 * @return 实体对象
	 */
	public T save(T entity);

	/**
	 * 更新已存在的对象
	 * 
	 * @param entity
	 *            實例對象
	 */
	public void update(T entity);

	/**
	 * 直接执行一个HQL的更新
	 * 
	 * @param HQL語句
	 * @return 受到影响的行数
	 */
	public int update(String hql);

	/**
	 * 根据ID删除记录
	 * 
	 * @param id
	 *            记录ID
	 */
	public T deleteById(Serializable id);

	/**
	 * 删除指定对象
	 * 
	 * @param entity
	 *            實例對象
	 */
	public void delete(T entity);

	/**
	 * 根據某屬性刪除對象
	 * 
	 * @param PROP_PARA
	 * 				屬性名
	 * @param value
	 * 				對於值
	 * @return
	 * 			受影響行數
	 */
	public int deleteByColumn(String PROP_PARA, Integer value);

	/**
	 * 保存或更新对象
	 * 
	 * @param entity
	 *            实体对象
	 * @return 实体对象
	 */
	public Object saveOrUpdate(Object entity);

	/*======================== 分页 ========================*/
	
	/**
	 * 根据Criteria加载分页，指定页大小和起始位置
	 */
	public PaginationSupport findPageByCriteria(final Criteria criteria,
			final int pageSize, final int startIndex);

	/**
	 * 根据Criteria加载分页，默认页大小，从第0条开始
	 */
	public PaginationSupport findPageByCriteria(final Criteria criteria);

	/**
	 * 根据Criteria加载分页，默认页大小，从第startIndex条开始
	 */
	public PaginationSupport findPageByCriteria(final Criteria criteria,
			final int startIndex);

	/**
	 * 根据Criteria统计总数
	 */
	public int getCountByCriteria(final Criteria criteria);

	/**
	 * 根据DetachedCriteria加载分页，指定页大小和起始位置
	 */
	public PaginationSupport findPageByCriteria(
			final DetachedCriteria detachedCriteria, final int pageSize,
			final int startIndex);

	/**
	 * 根据DetachedCriteria加载分页，默认页大小，从第0条开始
	 */
	public PaginationSupport findPageByCriteria(
			final DetachedCriteria detachedCriteria);

	/**
	 * 根据DetachedCriteria加载分页，默认页大小，从第startIndex条开始
	 */
	public PaginationSupport findPageByCriteria(
			final DetachedCriteria detachedCriteria, final int startIndex);

	/**
	 * 根据DetachedCriteria统计总数
	 */
	@SuppressWarnings("deprecation")
	public int getCountByCriteria(final DetachedCriteria detachedCriteria);

	/**
	 * 根据hql加载分页，指定页大小和起始位置
	 */
	public PaginationSupport findPageByQuery(final String hql,
			final int pageSize, final int startIndex, Object... values);

	/**
	 * 根据hql加载分页，默认页大小，从第0条开始
	 */
	public PaginationSupport findPageByQuery(final String hql, Object... values);

	/**
	 * 根据hql加载分页，默认页大小，从第startIndex条开始
	 */
	public PaginationSupport findPageByQuery(final String hql,
			final int startIndex, Object... values);

	/**
	 * 根据hql统计总数
	 */
	public int getCountByQuery(final String hql, Object... values);

	/**
	 * 创建Criteria对象
	 * 
	 * @param criterions
	 *            可变的Restrictions条件列表
	 */
	public Criteria createCriteria(Criterion... criterions);

	/**
	 * 创建Criteria对象，带排序字段与升降序字段
	 */
	public Criteria createCriteria(String orderBy, boolean isAsc,
			Criterion... criterions);

	/**
	 * 方法取自SpringSide. 创建Query对象.
	 * 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
	 * 留意可以连续设置,如下：
	 * 
	 * <pre>
	 * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
	 * </pre>
	 * 
	 * 调用方式如下：
	 * 
	 * <pre>
	 *        dao.createQuery(hql)
	 *        dao.createQuery(hql,arg0);
	 *        dao.createQuery(hql,arg0,arg1);
	 *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
	 * </pre>
	 * 
	 * @param values
	 *            可变参数.
	 */
	public Query createQuery(String hql, Object... values);

}